package com.example.mysql.学习笔记.高级.数据库的优化之索引.索引优化与查询优化;

public class 其他查询优化 {
}
/**
 * 12.1 EXISTS和IN的区分
 * 问题:
 * 不太理解哪种情况下应该使用EXISTS,哪种情况应该用IN。
 * 选择的标准是看能否使用表的索引吗?
 * 回答:
 * 索引是个前提，其实选择与否还是要看表的大小。你可以将选择的标准理解为小表驱动大表。
 * 在这种方式下效率是最高的。
 *
 * SELECT * FROM A WHERE cc IN (SELECT cc FROM B);//不相关子查询   以后面的表为基准  循环遍历前表
 * SELECT * FROM A WHERE EXISTS (SELECT cc FROM B WHERE B.cc=A.cc);//相关子查询  以前面的表为基准  循环遍历后表
 *
 * 上面两个  意思都一样  但是当A表大B表小是 用第一个
 *
 */

/**
 *
 * 12.2 COUNT(*)与COUNT(具体字段)效率
 *
 *  COUNT(*)和COUNT(1)本质上并没有区别
 * 如果是MyISAM存储引擎,    统计数据表的行数只需要O(1)的复杂度
 *    因为每张MyISAM的数据表都有一个meta信息存储了row_count值
 * 如果是InnoDB存储引擎,    统计数据表的行数只需要O(n)的复杂度
 *     因为InnoDB支持事务,采用行级锁和MVCC机制，所以无法像MyISAM一样
 *     维护一个row_count变量，因此需要采用扫描全表，是a(n)的复杂度,进行循环+计数的方式来完成统计。
 *
 * 在InnoDB引擎中，如果采用COUNT(具体字段)来统计数据行数,要尽量采用二级索引。
 * 因为主键采用的索引是聚簇索引，聚簇索引包含的信息多,明显会大于二级索引(非聚簇索引)。
 * 对于COUNT(*)和COUNT(1)来说，它们不需要查找具体的行，只是统计行数，
 * 系统会自动采用占用空间更小的二级索引来进行统计。
 * 如果有多个二级索引，会使用key_len（实际使用到的索引长度）小的二级索引进行扫描。
 * 当没有二级索引的时候，才会采用主键索引来进行统计。
 *
 */
/**
 * 12.3 关于SELECT(*)
 * 在表查询中，建议明确字段，不要使用*作为查询的字段列表,推荐使用SELECT <字段列表>查询。
 * 原因：
 * ①MySQL在解析的过程中，会通过查询数据字典将 "*" 按序转换成所有列名,这会大大的耗费资源和时间
 * ②无法使用覆盖索引()
 *
 */

/**
 * 12.4 LIMIT 1对优化的影响
 * 针对的是会扫描全表的SQL语句,如果你可以确定结果集只有一条，那么加上LIMIT 1的时候，
 * 当找到一条结果的时候就不会继续扫描了，这样会加快查询速度。
 * 如果数据表已经对字段建立了唯一索引，那么可以通过索引进行查询，
 * 不会全表扫描的话，就不需要加上LIMIT 1了。
 *
 */
/**
 * 12.5多使用COMMIT
 * 只要有可能，在程序中尽量多使用COMMIT,这样程序的性能得到提高，
 * 需求也会因为COMMIT所释放的资源而减少。
 * COMMIT所释放的资源:
 * ●回滚段上用于恢复数据的信息
 * ●被程序语句获得的锁
 * ●redo / undo log buffer中的空间
 * ●管理上述3种资源中的内部花费
 *
 *
 */